#include <iostream>
#include <cstdlib>
#include <mysql/mysql.h>

const char *host = "localhost";
const char *user = "connector";
const char *passwd = "366836573";
const char *db = "conn_test_db";
unsigned int port = 3369;

void connect_test()
{
    // std::cout << mysql_get_client_info() << std::endl;
    MYSQL *mysql = mysql_init(nullptr);

    if (mysql_real_connect(mysql, host, user, passwd, db, port, nullptr, 0) == nullptr)
    {
        std::cerr << "mysql connect fail, error: " << mysql_error(mysql) << std::endl;
        exit(1);
    }
    std::cout << "mysql connect success..." << std::endl;

    // input mysql query
    std::string sql;
    while (true)
    {
        std::cout << "MySQL> ";
        std::getline(std::cin, sql);
        if (sql == "quit")
        {
            std::cout << "Bye" << std::endl;
            break;
        }
        int n = mysql_query(mysql, sql.c_str());
        if (n == 0)
        {
            // 将获取的内容结果转储到MYSQL_RES res中，这是一个二维表结构
            MYSQL_RES *res = mysql_store_result(mysql);
            if (res == nullptr)
            {
                std::cout << "---OK---" << std::endl;
                continue;
            }
            // 获取res行数和列数
            int rows_num = mysql_num_rows(res);
            int fields_num = mysql_num_fields(res);
            // std::cout << "rows: " << rows_num << std::endl;
            // std::cout << "fields: " << fields_num << std::endl;

            // 输出列名称(mysql_fetch_field返回一组MYSQL_FIELD对象，每一个都保存着表对应列属性)
            MYSQL_FIELD *fields = mysql_fetch_field(res);
            for (int f = 0; f < fields_num; f++)
            {
                std::cout << fields[f].name << '\t';
            }
            std::cout << std::endl;
            // 输出res表的结果
            for (int i = 0; i < rows_num; i++)
            {
                // 获取一行结果, res中维护一个指针，获取一行后自动跳转到下一行，直到全部数据读完
                MYSQL_ROW cur_row = mysql_fetch_row(res);
                for (int j = 0; j < fields_num; j++)
                {
                    if (cur_row[j] != nullptr)
                        std::cout << cur_row[j] << '\t';
                    else
                        std::cout << "\t\t";
                }
                std::cout << std::endl;
            }

            mysql_free_result(res);
            std::cout << "---OK---" << std::endl;
        }
        else
        {
            std::cerr << mysql_error(mysql) << std::endl;
        }
    }

    mysql_close(mysql);
}

int main()
{
    connect_test();
    return 0;
}